//
//  PSBidTests.m
//  PrefCore
//
//  Created by Sergey on 1/16/14.
//  Copyright (c) 2014 Play-on-smart. All rights reserved.
//

#import <XCTest/XCTest.h>
#import "PSBid.h"

@interface PSBidTests : XCTestCase {
    NSArray *bidSuits;
}

-(void)setUp;

@end

@implementation PSBidTests

-(void)setUp {
    bidSuits = @[@(kSuitSpades), @(kSuitClubs), @(kSuitHearts), @(kSuitDiamonds), @(kSuitNone)];
}

-(void)testBidMisere {
    PSBid *misere = [PSBid bidMisere];
    XCTAssertNotNil(misere);
    XCTAssertEqual(misere.trump, kSuitNone);
    XCTAssertTrue(misere.isMisere);
}

-(void)testBidPlayWithTrump {
    for (NSNumber * sn in bidSuits) {
        PSCardSuit trump = (PSCardSuit)[sn intValue];
        for (PSTrickCount tricks = PS_BID_MIN ; tricks <= PS_BID_MAX ; tricks++) {
            PSBid *bid = [PSBid bidPlayWithTrump:trump tricks:tricks];
            XCTAssertNotNil(bid);
            XCTAssertEqual(bid.tricks, tricks);
            XCTAssertEqual(bid.trump, trump);
            XCTAssertTrue(bid.isPlay);
        }
    }
}

-(void)testBidNone {
    PSBid *bid = [PSBid bidNone];
    XCTAssertNotNil(bid);
    XCTAssertEqual(bid.type, kBidNone);
}

-(void)testBidWithoutThree {
    PSBid *bid = [PSBid bidWithoutThree];
    XCTAssertNotNil(bid);
    XCTAssertTrue(bid.isWihoutThree);
}

-(void)testBidPass {
    PSBid *bid = [PSBid bidPass];
    XCTAssertNotNil(bid);
    XCTAssertTrue(bid.isPass);
}

-(void)testBidWhist {
    PSBid *bid = [PSBid bidWhist];
    XCTAssertNotNil(bid);
    XCTAssertTrue(bid.isWhist);
}

-(void)testBidHalfWhis {
    PSBid *bid = [PSBid bidHalfWhist];
    XCTAssertNotNil(bid);
    XCTAssertTrue(bid.isHalfWhist);
}

-(void)testBidCheckTen {
    PSBid *bid = [PSBid bidCheckTen];
    XCTAssertNotNil(bid);
    XCTAssertTrue(bid.isCheckTen);
    XCTAssertEqual(bid.trump, kSuitNone);
}

-(void)testIsGreaterThanBid {
    PSBid *one = [PSBid bidPlayWithTrump:kSuitDiamonds tricks:6];
    PSBid *two = [PSBid bidPlayWithTrump:kSuitNone tricks:9];
    PSBid *three = [PSBid bidMisere];
    XCTAssertFalse([one isGreaterThanBid:two]);
    XCTAssertTrue([two isGreaterThanBid:one]);
    XCTAssertTrue([three isGreaterThanBid:one]);
    XCTAssertFalse([one isGreaterThanBid:one]);
    XCTAssertFalse([two isGreaterThanBid:two]);
    XCTAssertFalse([three isGreaterThanBid:two]);
}

-(void)testNextBid {
    PSBid *last = [PSBid bidPlayWithTrump:kSuitSpades tricks:PS_BID_MIN];
    int count = 0;
    while (last) {
        PSBid *next = [last nextBid];
        if (next != nil) {
            XCTAssertTrue(
                (next.trump == kSuitSpades && last.trump == kSuitNone && next.tricks == last.tricks+1)
            ||  (next.tricks == last.tricks && next.trump == PSCardSuitNext(last.trump))
            ,   @"Incorrect bid after %@: %@", last, next
            );
        } else {
            XCTAssertEqual(last.trump, kSuitNone);
            XCTAssertEqual(last.tricks, PS_BID_MAX);
        }
        last = next;
        count++;
    }
    XCTAssertEqual(count, 25);
}

-(void)testBidIncrement {
    for (NSNumber * sn in bidSuits) {
        PSCardSuit trump = (PSCardSuit)[sn intValue];
        PSBid *bid = [PSBid bidPlayWithTrump:trump tricks:PS_BID_MIN];
        while (bid.tricks != PS_BID_MAX) {
            XCTAssertTrue(bid.canIncrementTricks);
            PSBid *next = [bid incrementTricks];
            XCTAssertNotNil(next);
            XCTAssertEqual(bid.trump, next.trump);
            XCTAssertEqual(next.tricks, (PSTrickCount)(bid.tricks+1));
            bid = next;
        }
        XCTAssertEqual(bid.trump, trump);
        XCTAssertFalse(bid.canIncrementTricks);
        PSBid *next = [bid incrementTricks];
        XCTAssertEqualObjects(bid, next);
    }
}

-(void)testBidDecrement {
    for (NSNumber * sn in bidSuits) {
        PSCardSuit trump = (PSCardSuit)[sn intValue];
        PSBid *bid = [PSBid bidPlayWithTrump:trump tricks:PS_BID_MAX];
        while (bid.tricks != PS_BID_MIN) {
            XCTAssertTrue(bid.canDecrementTricks);
            PSBid *next = [bid decrementTricks];
            XCTAssertNotNil(next);
            XCTAssertEqual(bid.trump, next.trump);
            XCTAssertEqual(next.tricks, (PSTrickCount)(bid.tricks-1));
            bid = next;
        }
        XCTAssertEqual(bid.trump, trump);
        XCTAssertFalse(bid.canDecrementTricks);
        PSBid *next = [bid decrementTricks];
        XCTAssertEqualObjects(bid, next);
    }
}

-(void)testBidDescription {
    XCTAssertEqualObjects(@"misere", [[PSBid bidMisere] description]);
    XCTAssertEqualObjects(@"pass", [[PSBid bidPass] description]);
    XCTAssertEqualObjects(@"whist_half", [[PSBid bidHalfWhist] description]);
    XCTAssertEqualObjects(@"whist_full", [[PSBid bidWhist] description]);
    XCTAssertEqualObjects(@"without3", [[PSBid bidWithoutThree] description]);
    XCTAssertEqualObjects(@"check10", [[PSBid bidCheckTen] description]);
    XCTAssertEqualObjects(@"6♠", [[PSBid bidPlayWithTrump:kSuitSpades tricks:6] description]);
    XCTAssertEqualObjects(@"7♣", [[PSBid bidPlayWithTrump:kSuitClubs tricks:7] description]);
    XCTAssertEqualObjects(@"8♦", [[PSBid bidPlayWithTrump:kSuitDiamonds tricks:8] description]);
    XCTAssertEqualObjects(@"9♥", [[PSBid bidPlayWithTrump:kSuitHearts tricks:9] description]);
    XCTAssertEqualObjects(@"10.", [[PSBid bidPlayWithTrump:kSuitNone tricks:10] description]);
}

@end



